package com.yd.quartz.handler;

import com.alibaba.fastjson.JSONObject;
import com.yd.quartz.domain.JobInfo;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * job处理器
 */

@Service
public class JobHander {

    @Autowired
    private Scheduler scheduler;


    public void addJob(JobInfo jobInfo) throws SchedulerException, ClassNotFoundException {

        Objects.requireNonNull(jobInfo,"任务信息不能为空");

        //生成job key
        JobKey jobKey = JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup());

        //当前任务不存在才进行添加
        if(!scheduler.checkExists(jobKey)){
            Class<Job> jobClass = (Class<Job>) Class.forName(jobInfo.getClassName());

            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobKey)
                    .withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup())
                    .withDescription(jobInfo.getJobName())
                    .build();


            //配置信息
            jobDetail.getJobDataMap().put("config",jobInfo.getConfig());


            //定义触发器
            TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getTriggerName(), jobInfo.getTriggerGroup());

            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobInfo.getCron()))
                    .build();


            scheduler.scheduleJob(jobDetail,trigger);


        }else{
            throw new SchedulerException(jobInfo.getJobName()+"任务已经存在，无需重复添加");

        }


    }


    /**
     * 任务暂停
     * @param jobGroup
     * @param jobName
     */
    public void pauseJob(String jobGroup,String jobName) throws SchedulerException {

        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);


        if(scheduler.checkExists(jobKey)){

            scheduler.pauseJob(jobKey);

        }
    }

    /**
     * 继续任务
     * @param jobGroup
     * @param jobName
     */
    public void continueJob(String jobGroup,String jobName) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        
        if(scheduler.checkExists(jobKey)){
            scheduler.resumeJob(jobKey);
        }

    }


    /**
     * 删除job
     * @param jobGroup
     * @param jobName
     * @return
     * @throws SchedulerException
     */
    public boolean deleteJob(String jobGroup,String jobName) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        
        if(scheduler.checkExists(jobKey)){
            
           return scheduler.deleteJob(jobKey);
        }
        
        return false;

    }

    /**
     * 获取任务信息
     * @param jobGroup
     * @param jobName
     * @return
     */
    public JobInfo getJobInfo(String jobGroup,String jobName) throws SchedulerException {

        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        
        if(!scheduler.checkExists(jobKey)){
            return null;
        }

        List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
        
        
        if(Objects.isNull(triggers)){
            throw new SchedulerException("未获取到触发器信息");
        }


        TriggerKey triggerKey = triggers.get(0).getKey();

        Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);

        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        
        
        JobInfo jobInfo  =new JobInfo();

        jobInfo.setJobName(jobName);
        jobInfo.setJobGroup(jobGroup);

        jobInfo.setTriggerName(triggerKey.getName());
        jobInfo.setTriggerGroup(triggerKey.getGroup());

        jobInfo.setClassName(jobDetail.getJobClass().getName());


        jobInfo.setStatus(triggerState.toString());

        if(Objects.nonNull(jobDetail.getJobDataMap())){
            jobInfo.setConfig(JSONObject.toJSONString(jobDetail.getJobDataMap()));
        }

        CronTrigger trigger = (CronTrigger)triggers.get(0);
        jobInfo.setCron(trigger.getCronExpression());

        return jobInfo;
    }
}
